﻿/**
 * @file guild_saver.hpp
 * @date 2021/05/17 09:05
 *
 * @author harrybao (harrybao@123u.com)
 *
 * @brief 公会保存
 *
 * @version v1.0.0
 *
 * @copyright Copyright © 2021 All Rights Reserved 上海欢乐互娱网络科技有限公司
 *
 * @par history:
 * <table>
 * <tr><th>Date                     <th>Version     <th>Author <th>Description
 * <tr><td>2021/05/17 09:05         <td>1.0.0       <td>harrybao
 * <td>创建初始版本
 * </table>
 */

#pragma once

#include <sstream>

#include "guild/guild.h"
#include "redis/service_redis_fwd.hpp"

namespace guild_service {
namespace detail {

/**
 * @brief 同步保存公会Id
 *
 * @param service_name 公会服务名
 * @param guild_str_list 公会id字符串列表
 * @return 加载结果
 * @retval true 加载成功
 * @retval false 加载失败
 */
static bool SaveLastGuildId(const std::string &service_name,
                     const guild_id_type guild_id) {
  std::stringstream ss;
  ss << "SET lastguildid " << guild_id;
  auto result = redis_command_co(service_name, ss.str(), kRedisCommonTimeOut);
  if (!result) {
    LOG_FAIL("redis处理失败 命令:%s 服务名:%s", ss.str().c_str(),
             service_name.c_str());
    return false;
  }

  if (!result->is_success()) {
    LOG_FAIL("redis处理失败 命令:%s 错误:%s 错误码:%u 服务名:%s",
             result->get_command().c_str(), result->get_error().c_str(),
             static_cast<uint32_t>(result->get_error_code()),
             service_name.c_str());
    return false;
  }

  LOG_DEBUG("redis同步保存公会id成功 命令:%s 服务名:%s",
            result->get_command().c_str(), service_name.c_str());

  return true;
}

/**
 * @brief 同步保存角色唯一id获取公会id
 *
 * @param service_name 公会服务名
 * @param op 操作
 * @param role_uuid 角色唯一id
 * @param guild_id  公会id
 * @return true 保存成功
 * @return false 保存失败
 */
static bool SaveGuildIdByRole(const std::string &service_name, const std::string &op,
                       const role_uuid_type role_uuid,
                       const guild_id_type guild_id) {
  std::stringstream ss;
  ss << op << kLoadGuildIdByRoleKeyPrefix << role_uuid;
  if (op == kRedisSetOp) {
    ss << " " << guild_id;
  }

  auto result = redis_command_co(service_name, ss.str(), kRedisCommonTimeOut);
  if (!result) {
    LOG_FAIL("redis处理失败 命令:%s 服务名:%s", ss.str().c_str(),
             service_name.c_str());
    return false;
  }
  if (!result->is_success()) {
    LOG_FAIL("redis处理失败 命令:%s 错误:%s 错误码:%u 服务名:%s",
             result->get_command().c_str(), result->get_error().c_str(),
             static_cast<uint32_t>(result->get_error_code()),
             service_name.c_str());
    return false;
  }

  LOG_DEBUG("redis保存角色id映射公会id成功 命令:(%s) 服务名:%s",
            result->get_command().c_str(), service_name.c_str());

  return true;
}

/**
 * @brief 
 * 
 * @param service_name 
 * @param op 
 * @param token 
 * @param role_uuid 
 * @return true 
 * @return false 
 */
static bool SaveTokenRoleUuid(const std::string &service_name, const std::string &op,
                       const token_type token,
                       const role_uuid_type role_uuid) {
  std::stringstream ss;
  ss << op << kTokenKeyPrefix << token;
  if (op == kRedisSetOp) {
    ss << " " << role_uuid;
  }

  auto result = redis_command_co(service_name, ss.str(), kRedisCommonTimeOut);
  if (!result) {
    LOG_FAIL("redis处理失败 命令:%s 服务名:%s", ss.str().c_str(),
             service_name.c_str());
    return false;
  }
  if (!result->is_success()) {
    LOG_FAIL("redis处理失败 命令:%s 错误:%s 错误码:%u 服务名:%s",
             result->get_command().c_str(), result->get_error().c_str(),
             static_cast<uint32_t>(result->get_error_code()),
             service_name.c_str());
    return false;
  }

  LOG_DEBUG("redis保存凭证映射角色唯一id成功 命令:(%s) 服务名:%s",
            result->get_command().c_str(), service_name.c_str());

  return true;
}

/**
 * @brief 生成测试随机角色唯一id
 * 
 * @param service_name 服务名
 * @return true 生成成功
 * @return false 生成失败
 */
static bool TestGenerateRandomRoleUuid(const std::string &service_name) {
  for (std::size_t i = 0; i < kTestAccountList.size(); ++i) {
    std::stringstream ss;
    kTestRoleUuidList[i] = (1000 + rand() % 1000);
    kTestTokenList[i] = (1000 + rand() % 1000);

    ss << kRedisSetOp << kAccountKeyPrefix << kTestAccountList[i] << ":"
       << kTestPasswdList[i] << " " << kTestRoleUuidList[i];

    if (!redis_command_async(
            service_name, ss.str(), kRedisCommonTimeOutAsync,
            [](const redis_result_type &result, std::uint64_t) {
            },
            0)) {
    } else {
    }
  }
  return true;
}

/**
 * @brief 获取测试角色唯一id
 * 
 * @param account 
 * @param passwd 
 * @return role_uuid_type 
 */
static role_uuid_type TestGetRoleUuid(const std::string &account,
                                      const std::string &passwd) {
  for (std::size_t i = 0; i < kTestAccountList.size(); ++i) {
    if (kTestAccountList[i] == account && kTestPasswdList[i] == passwd) {
      return kTestRoleUuidList[i];
    }
  }
  return kInvalidRoleUuid;
}

/**
 * @brief 获取测试凭证
 * 
 * @param account 
 * @param passwd 
 * @return token_type 
 */
static token_type TestGetToken(const std::string &account,
                                      const std::string &passwd) {
  for (std::size_t i = 0; i < kTestAccountList.size(); ++i) {
    if (kTestAccountList[i] == account && kTestPasswdList[i] == passwd) {
      return kTestTokenList[i];
    }
  }
  return kInvalidToken;
}

/**
 * @brief 测试清空redis
 * 
 * @param service_name 服务名
 * @return true 
 * @return false 
 */
static bool TestFlushAll(const std::string &service_name) {
  std::stringstream ss;
  ss << "FLUSHALL";
  if (!redis_command_async(
          service_name, ss.str(), kRedisCommonTimeOutAsync,
          [](const redis_result_type &result, std::uint64_t) {}, 0)) {
  } else {
    LOG_FAIL("redis运行失败 命令:(%s)", ss.str().c_str());
  }

  return true;
}

}  // namespace detail
}  // namespace guild_service